package cn.mdmm.service.impl.weixin;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.weixin.api.WxMenu;
import com.weixin.core.TokenFactory;
import com.weixin.pojo.menu.Menu;
import com.weixin.pojo.menu.Menus;

import cn.mdmm.entity.weixin.WxAccountConfigModel;
import cn.mdmm.entity.weixin.WxAccountInfoModel;
import cn.mdmm.entity.weixin.WxAccountMenuModel;
import cn.mdmm.entity.weixin.WxAccountReplyMsgModel;
import cn.mdmm.mapper.weixin.WxAccountMenuMapper;
import cn.mdmm.service.weixin.WxAccountConfigService;
import cn.mdmm.service.weixin.WxAccountMenuMsgService;
import cn.mdmm.service.weixin.WxAccountMenuService;
import cn.mdmm.service.weixin.WxAccountReplyMsgService;
import cn.modoumama.service.base.impl.BaseServiceImpl;

/**
 * 类名称：WxAccountMenu对象定义<br>
 * 类描述：微信自定义菜单业务实现类<br>
 * 类生产方式：工具自动生成代码<br>
 * 创建人：dengqiang<br>
 * 创建时间：2017-07-05 15:28:36<br>
 * 修改人： <br>
 * 修改时间：<br>
 * 修改备注：<br>
 * 
 * @version V1.0
 */

@Service
public class WxAccountMenuServiceImpl extends BaseServiceImpl<WxAccountMenuModel, Integer>
		implements WxAccountMenuService {
	Logger logger = LoggerFactory.getLogger(getClass());

	@Autowired
	public void setGenericMapper(WxAccountMenuMapper genericMapper) {
		super.setGenericMapper(genericMapper);
	}

	@Autowired
	WxAccountMenuMapper currMapper;
	@Autowired
	WxAccountMenuMsgService wxAccountMenuMsgService;
	@Autowired
	WxAccountConfigService wxAccountConfigService;
	@Autowired
	WxAccountReplyMsgService wxAccountReplyMsgService;

	// ------------------请在此添加自定义方法（开始）------------------

	@Override
	public void cleanWxAccountMenu(Integer wxAccountId) {
		currMapper.cleanWxAccountMenu(wxAccountId);
	}

	@Override
	public void initMenu(WxAccountInfoModel wxAccountInfoModel) {
		logger.info("初始化公众号{}菜单开始", wxAccountInfoModel.getAccountNo());

		Integer wxAccountId = wxAccountInfoModel.getId();
		logger.info("清空化公众号{}菜单", wxAccountInfoModel.getAccountNo());
		cleanWxAccountMenu(wxAccountId);

		String customMenuStr = WxMenu.getToMenu(TokenFactory.getWxConfig(wxAccountInfoModel.getAccountNo()));
		WxAccountConfigModel wxAccountConfigModel = new WxAccountConfigModel();
		wxAccountConfigModel.setWxAccountId(wxAccountId);
		wxAccountConfigModel.setDateType(1);
		wxAccountConfigModel.setDateJson(customMenuStr);
		wxAccountConfigService.insert(wxAccountConfigModel);

		JSONObject customMenu = JSON.parseObject(customMenuStr);
		initMenu(wxAccountId, customMenu);
		logger.info("初始化公众号{}菜单结束", wxAccountInfoModel.getAccountNo());
	}

	@Override
	public List<WxAccountMenuModel> getWxAccountMenu(Integer wxAccountId) {
		WxAccountMenuModel wxAccountMenuModel = new WxAccountMenuModel();
		wxAccountMenuModel.setWxAccountId(wxAccountId);
		return getListByModel(wxAccountMenuModel);
	}

	@Override
	public void createWxMenu(WxAccountInfoModel wxAccountInfoModel) {
		final Integer wxAccountId = wxAccountInfoModel.getId();
		// 所有的菜单
		List<WxAccountMenuModel> wxAccountMenus = getWxAccountMenu(wxAccountId);
		// 一级菜单
		List<WxAccountMenuModel> topMenus = new ArrayList<>();
		Map<Integer, WxAccountMenuModel> allMenus = new TreeMap<>();

		// 需要发送到微信的数据
		final Menus menus = new Menus();

		for (WxAccountMenuModel wxAccountMenu : wxAccountMenus) {
			allMenus.put(wxAccountMenu.getId(), wxAccountMenu);
		}

		for (Entry<Integer, WxAccountMenuModel> entry : allMenus.entrySet()) {
			WxAccountMenuModel wxAccountMenu = entry.getValue();
			if (wxAccountMenu != null) {
				if (wxAccountMenu.getPid() != null) {
					allMenus.get(wxAccountMenu.getPid()).addChildrens(wxAccountMenu);
				} else {
					topMenus.add(wxAccountMenu);
				}
			}
		}

		for (WxAccountMenuModel wxAccountMenu : topMenus) {
			Menu menu = toMenu(wxAccountMenu);
			menus.add(menu);
		}

		logger.info("公众号{}创建的菜单：{}", wxAccountInfoModel.getAccountNo(), JSON.toJSON(menus));
		String retJson = WxMenu.addMenu(TokenFactory.getWxConfig(wxAccountInfoModel.getAccountNo()), menus);
		logger.info("公众号{}创建的菜单,微信的返回数据：{}", wxAccountInfoModel.getAccountNo(), retJson);
	}
	// ------------------请在此添加自定义方法（结束）------------------

	/**
	 * <p>
	 * 保存自定义菜单
	 * </p>
	 * 
	 * @param wx_id
	 * @param customMenu
	 *            创建人：邓强 <br>
	 *            创建时间：2017年7月4日 下午2:49:02 <br>
	 */
	private void initMenu(Integer wx_id, JSONObject customMenu) {
		logger.info("自定义菜单：{}", customMenu);
		if (customMenu != null) {
			// 获取菜单
			JSONObject selfmenu_info = customMenu.getObject("selfmenu_info", JSONObject.class);
			// 获取菜单的按钮
			if (selfmenu_info != null) {
				JSONArray button = selfmenu_info.getJSONArray("button");
				// 解析一级菜单
				if (button != null) {
					// 插入一级菜单
					for (Object object : button) {
						JSONObject menus = (JSONObject) object;
						JSONObject sub_button = menus.getObject("sub_button", JSONObject.class);
						menus.remove("sub_button");
						Integer menuId = insetMenu(wx_id, null, menus);
						if (sub_button != null) {
							JSONArray buttonlist = sub_button.getJSONArray("list");
							if (buttonlist != null && buttonlist.size() > 0) {
								// 插入二级菜单
								for (Object menuObj : buttonlist) {
									insetMenu(wx_id, menuId, (JSONObject) menuObj);
								}
							}
						}
					}
				}
			}
		}
	}

	/**
	 * 插入菜单<br>
	 * <br>
	 * 创建人：邓强 <br>
	 * 创建时间：2017年10月31日 下午12:07:49 <br>
	 * 修改人： <br>
	 * 修改时间：2017年10月31日 下午12:07:49 <br>
	 * 修改备注： <br>
	 * 
	 * @param wx_id
	 *            微信号Id
	 * @param id
	 *            一级菜单的Id
	 * @param menus
	 * @return
	 */
	private Integer insetMenu(Integer wx_id, Integer id, JSONObject menus) {
		WxAccountMenuModel menu = new WxAccountMenuModel();
		menus.remove("news_info");
		menu = JSON.toJavaObject((JSON) menus, WxAccountMenuModel.class);
		menu.setWxAccountId(wx_id);
		menu.setPid(id);

		if (menu.getType() != null) {
			switch (menu.getType()) {
			case "img":
			case "voice":
				menu.setType("media_id");
				menu.setMediaId(menus.getString("value"));
				break;
			case "news":
				menu.setType("view_limited");
				menu.setMediaId(menus.getString("value"));
				break;
			}
		}

		// 插入菜单
		insert(menu);

		if ("text".equals(menu.getType())) {
			menu.setType("click");
			menu.setKey("menu_" + menu.getId());
			super.updateById(menu);
			WxAccountReplyMsgModel wxAccountReplyMsgModel = new WxAccountReplyMsgModel();
			wxAccountReplyMsgModel.setWxAccountId(wx_id);
			wxAccountReplyMsgModel.setType(0);
			wxAccountReplyMsgModel.setMsgType("text");
			wxAccountReplyMsgModel.setContent(menus.getString("value"));
			wxAccountReplyMsgModel.setCreateTime(new Date());
			wxAccountReplyMsgService.insert(wxAccountReplyMsgModel);
			wxAccountMenuMsgService.insert(menu.getId(), wxAccountReplyMsgModel.getId());
		}
		return menu.getId();
	}

	private Menu toMenu(WxAccountMenuModel wxAccountMenu) {
		Menu menu = new Menu();
		if (StringUtils.isNotBlank(wxAccountMenu.getType())) {

			switch (wxAccountMenu.getType()) {
			case "media_id":
			case "view_limited":
				menu.setMedia_id(wxAccountMenu.getMediaId());
				break;
			case "view":
				menu.setUrl(wxAccountMenu.getUrl());
				break;
			case "miniprogram":
				menu.setUrl(wxAccountMenu.getUrl());
				menu.setAppid(wxAccountMenu.getAppid());
				menu.setPagepath(wxAccountMenu.getPagepath());
				break;
			case "click":
			case "scancode_waitmsg":// 扫码带提示
			case "scancode_push":// 扫码推事件
			case "pic_sysphoto":// 系统拍照发图
			case "pic_photo_or_album":// 拍照或者相册发图
			case "pic_weixin":// 微信相册发图
			case "location_select":// 发送位置
				menu.setKey(wxAccountMenu.getKey());
				break;
			}
		}

		menu.setName(wxAccountMenu.getName());
		menu.setType(wxAccountMenu.getType());

		if (wxAccountMenu.getChildrens().size() > 0) {
			for (WxAccountMenuModel wxAccountMenu2 : wxAccountMenu.getChildrens()) {
				menu.add(toMenu(wxAccountMenu2));
			}
		}
		return menu;
	}
}
